package boc.sx.gateway.socket.client.support;

import io.netty.channel.ChannelInitializer;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/*
 * @author zmx
 * @date 2022/8/18 10:38
 */
@Component
public class InitializerFactory implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    public static HashMap<String, ChannelInitializer> channelInitializerMap ;


    public static ChannelInitializer getInitializer(String protocol,String requestCode,Object msg,String requestPath){
        if(channelInitializerMap ==null){
            channelInitializerMap = getProtocolChannelInitializer();
        }
        ChannelInitializer channelInitializer = channelInitializerMap.get(protocol);
        if( channelInitializer instanceof ChannelInitializerBuilder) {
            channelInitializer =  ((ChannelInitializerBuilder) channelInitializer).config(requestCode, msg, requestPath);
        }
        return channelInitializer;
    }

    public static HashMap<String, ChannelInitializer> getProtocolChannelInitializer(){
        HashMap<String, ChannelInitializer> res = new HashMap<>();
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Protocol.class);
        for (Object bean : beans.values()) {
            if(bean!=null){
                Annotation[] annotations = bean.getClass().getAnnotations();
                for (Annotation annotation:annotations){
                    if(annotation.annotationType() == Protocol.class && bean instanceof ChannelInitializer && bean instanceof  ChannelInitializerBuilder){
                        Protocol anno = (Protocol) annotation;
                        res.put(anno.value(),(ChannelInitializer) bean);
                        break;
                    }
                }
            }
        }
        return res;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
